package com.school.sports.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.school.sports.dto.EnrollmentDTO;
import com.school.sports.entity.Enrollment;

import java.util.List;

/**
 * 报名服务接口
 * 定义了报名相关的业务方法，包含优化的关联查询
 */
public interface EnrollmentService extends IService<Enrollment> {
    /**
     * 分页查询报名列表（基础版本）
     * @param page 分页对象
     * @param queryWrapper 查询条件
     * @return 包含报名数据的分页对象
     */
    IPage<Enrollment> page(Page<Enrollment> page, com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Enrollment> queryWrapper);

    /**
     * 分页查询报名信息（包含用户和项目详细信息）
     * 使用JOIN查询避免N+1问题
     *
     * @param page 分页参数
     * @param userId 用户ID（可选）
     * @param projectId 项目ID（可选）
     * @param status 报名状态（可选）
     * @return 分页结果
     */
    IPage<EnrollmentDTO> pageEnrollmentsWithDetails(
            Page<EnrollmentDTO> page,
            Long userId,
            Long projectId,
            String status
    );

    /**
     * 根据ID查询报名详情（包含用户和项目信息）
     * @param id 报名ID
     * @return 报名详情
     */
    Enrollment getEnrollmentWithDetails(Long id);

    /**
     * 根据ID查询报名详细信息（包含用户和项目信息）
     * 使用JOIN查询避免N+1问题
     *
     * @param id 报名ID
     * @return 报名详细信息
     */
    EnrollmentDTO getEnrollmentDetailsById(Long id);

    /**
     * 学生报名项目
     * @param userId 用户ID
     * @param projectId 项目ID
     * @param healthStatement 健康声明
     * @return 报名结果
     */
    boolean enrollProject(Long userId, Long projectId, String healthStatement);

    /**
     * 取消报名
     * @param id 报名ID
     * @param userId 当前用户ID（用于权限验证）
     * @return 取消结果
     */
    boolean cancelEnrollment(Long id, Long userId);

    /**
     * 审核报名
     * @param id 报名ID
     * @param status 审核结果
     * @param rejectReason 驳回原因（驳回时必填）
     * @return 审核结果
     */
    boolean auditEnrollment(Long id, String status, String rejectReason);

    /**
     * 批量审核报名
     * @param ids 报名ID列表
     * @param status 审核结果
     * @param rejectReason 驳回原因
     * @return 审核结果
     */
    boolean batchAuditEnrollment(List<Long> ids, String status, String rejectReason);

    /**
     * 检查用户是否已报名某项目
     * @param userId 用户ID
     * @param projectId 项目ID
     * @return 是否已报名
     */
    boolean isUserEnrolled(Long userId, Long projectId);

    /**
     * 根据用户ID查询报名列表
     * @param userId 用户ID
     * @return 报名列表
     */
    List<Enrollment> getEnrollmentsByUserId(Long userId);

    /**
     * 根据用户ID查询报名信息（包含项目详细信息）
     * 使用JOIN查询避免N+1问题
     *
     * @param userId 用户ID
     * @return 报名信息列表
     */
    List<EnrollmentDTO> getEnrollmentDetailsByUserId(Long userId);

    /**
     * 根据项目ID查询报名列表
     * @param projectId 项目ID
     * @return 报名列表
     */
    List<Enrollment> getEnrollmentsByProjectId(Long projectId);

    /**
     * 根据项目ID查询报名信息（包含用户详细信息）
     * 使用JOIN查询避免N+1问题
     *
     * @param projectId 项目ID
     * @return 报名信息列表
     */
    List<EnrollmentDTO> getEnrollmentDetailsByProjectId(Long projectId);

    /**
     * 根据状态查询报名列表
     * @param status 报名状态
     * @return 报名列表
     */
    List<Enrollment> getEnrollmentsByStatus(String status);

    /**
     * 统计某项目的报名人数
     * @param projectId 项目ID
     * @return 报名人数
     */
    long countEnrollmentsByProjectId(Long projectId);

    /**
     * 统计某状态的报名数量
     * @param status 报名状态
     * @return 报名数量
     */
    long countEnrollmentsByStatus(String status);

    /**
     * 获取所有报名状态
     * @return 报名状态列表
     */
    List<String> getAllEnrollmentStatuses();

    /**
     * 检查项目是否可以报名
     * @param projectId 项目ID
     * @return 是否可以报名
     */
    boolean canEnrollProject(Long projectId);

    /**
     * 根据用户ID和项目ID获取报名信息
     * @param userId 用户ID
     * @param projectId 项目ID
     * @return 报名信息
     */
    Enrollment getByUserIdAndProjectId(Long userId, Long projectId);
}